home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Converters / Convert_TEXT / Source / shared.subproj / TextFile.m < prev   
Text File  |  1995-06-12  |  13KB  |  349 lines

  1. /***********************************************************************\
  2. Common class for accessing text files in all Convert programs
  3. Copyright (C) 1993 David John Burrowes
  4.  
  5. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version.
  6.  
  7. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  8.  
  9. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  10.  
  11. The author, David John Burrowes, can be reached at:
  12.     davidjohn@kira.net.netcom.com
  13.     David John Burrowes
  14.     1926 Ivy #10
  15.     San Mateo, CA 94403-1367
  16. \***********************************************************************/
  17.  
  18. #import <streams/streams.h>
  19. #import <stdio.h>
  20. #import <string.h>    // for strlen
  21. #import "TextFile.h"
  22.  
  23.  
  24. //    We are assuming our superclass has already imported this.  If not, you'll get an
  25. //    error below, indicating that this wont work (see  LookAtNextCharacter
  26. //    #import <streams/streams.h>
  27.  
  28. @implementation TextFile
  29.  
  30.  
  31. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  32. //    Method:        GetHexByte
  33. //    Parameters:    none
  34. //    Returns:     The byte corresponding to the hex values in the file
  35. //    Stores:        error info
  36. //                The byte corresponding to the hex values in the file
  37. //    Description:
  38. //        This reads in a pair of hex difits, and returns their integer form (i.e reading
  39. //        '41' will be returned as the integer 65.
  40. //    *WARNING*:
  41. //        This assumes it is working as a subclass of a File object that is going to
  42. //        have a NXstream open.
  43. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  44. - (Byte) GetHexByte
  45. {
  46.     Integer        theInt = 0;
  47.     Integer        num;
  48.     
  49.     [self ResetResults];
  50.     if (FileIsOpen == NO)
  51.         [self StoreErrorCode: ERR_FILENOTOPEN AndText: "Unable to read from a closed file"];
  52.     else
  53.     {
  54.         num = NXScanf(TheFile, "%2x", &theInt);
  55.         if (num != 1)
  56.             [self StoreErrorCode: ERR_BADREAD AndText: "Unable to read a hex value"];
  57.         else
  58.             [self StoreErrorCode: ERR_OK AndText: "Got the byte just fine"];
  59.     }
  60.     [self StoreInteger: theInt];
  61.     return theInt;
  62. }
  63.  
  64.  
  65. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  66. //    Method:        GetNumber
  67. //    Parameters:    none
  68. //    Returns:     The number read from the text file
  69. //    Stores:        error info
  70. //                The number read from the text file
  71. //    Description:
  72. //        This reads in a series of characters, and converts them to a signed integer
  73. //        value.
  74. //    *WARNING*:
  75. //        This assumes it is working as a subclass of a File object that is going to
  76. //        have a NXstream open.
  77. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  78. - (Integer) GetNumber
  79. {
  80.     Integer        theInt = 0;
  81.     Integer        num;
  82.     
  83.     [self ResetResults];
  84.     if (FileIsOpen == NO)
  85.         [self StoreErrorCode: ERR_FILENOTOPEN AndText: "Unable to read from a closed file"];
  86.     else
  87.     {
  88.         num = NXScanf(TheFile, "%d", &theInt);
  89.         if (num != 1)
  90.             [self StoreErrorCode: ERR_BADREAD AndText: "Unable to read a hex value"];
  91.         else
  92.             [self StoreErrorCode: ERR_OK AndText: "Got the byte just fine"];
  93.     }
  94.     [self StoreInteger: theInt];
  95.     return theInt;
  96. }
  97.  
  98.  
  99.  
  100. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  101. //    Method:        GetCharacter:
  102. //    Parameters:    none
  103. //    Returns:     The character found
  104. //    Stores:        error info
  105. //                The character found
  106. //    Description:
  107. //        This merely reads a character in from the file and returns it, unless an error
  108. //        occurrs.  Note that if the file is open, our error results are those which
  109. //        Read:BytesInto: generates.
  110. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  111. - (Character) GetCharacter
  112. {
  113.     Character    theBuffer = NullCharacter;
  114.     
  115.     [self ResetResults];
  116.     if (FileIsOpen == NO)
  117.         [self StoreErrorCode: ERR_FILENOTOPEN AndText: "Unable to read from a closed file"];
  118.     else
  119.     {
  120.         [self Read: 1 BytesInto: &theBuffer];
  121.         if ([self   GetErrorCode] != ERR_OK)
  122.         {
  123.             [self StoreErrorCode: ERR_BADREAD AndText: "Read error.  let's call it eof"];
  124.             FileLocation = fileAtEOF;
  125.         }
  126.         else
  127.             [self StoreErrorCode: ERR_OK AndText: "OK"];
  128.     }
  129.     
  130.     [self StoreCharacter: theBuffer];
  131.     return theBuffer;
  132. }
  133.  
  134.  
  135. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  136. //    Method:        LookAtNextCharacter
  137. //    Parameters:    none
  138. //    Returns:     The character found
  139. //    Stores:        error info
  140. //                The character found
  141. //    Description:
  142. //        This locates the next character waiting to be read, and returns it without
  143. //        moving past it.
  144. //    *WARNING*:
  145. //        This assumes it is working as a subclass of a File object that is going to
  146. //        have a NXstream open that can do ungetting!!!!!!
  147. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  148. - (Character) LookAtNextCharacter
  149. {
  150.     Character    theCharacter = NullCharacter;
  151.     
  152.     [self ResetResults];
  153.     if (FileIsOpen == NO)
  154.         [self StoreErrorCode: ERR_FILENOTOPEN AndText: "Unable to peek at a closed file"];
  155.     else
  156.     {
  157.         if (NXAtEOS(TheFile) == YES)
  158.         {
  159.             [self StoreErrorCode: ERR_BADREAD AndText: "Read error.  let's call it eof"];
  160.             FileLocation = fileAtEOF;
  161.         }
  162.         else
  163.         {
  164.             //
  165.             //    NeXT doesn't document what error codes these generate, very well..
  166.             //
  167.             theCharacter =  NXGetc(TheFile);
  168.             NXUngetc(TheFile);
  169.             [self StoreErrorCode: ERR_OK AndText: "Read the character OK"];
  170.         }
  171.     }
  172.     [self StoreCharacter: theCharacter];
  173.     return theCharacter;
  174. }
  175.  
  176.  
  177.  
  178. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  179. //    Method:        UnGetCharacter
  180. //    Parameters:    none
  181. //    Returns:     none
  182. //    Stores:        error info
  183. //    Description:
  184. //        Thgis simply ungets whatever the last character got was.
  185. //        (due to NeXT limitiations, you can't call this twice in a row to unget the last 2)
  186. //    *WARNING*:
  187. //        This assumes it is working as a subclass of a File object that is going to
  188. //        have a NXstream open that can do ungetting!!!!!!
  189. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  190. - UnGetCharacter
  191. {
  192.     [self ResetResults];
  193.     if (FileIsOpen == NO)
  194.         [self StoreErrorCode: ERR_FILENOTOPEN AndText: "Unable to peek at a closed file"];
  195.     else
  196.     {
  197.         if (NXAtEOS(TheFile) == YES)
  198.         {
  199.             [self StoreErrorCode: ERR_BADREAD AndText: "Read error.  let's call it eof"];
  200.             FileLocation = fileAtEOF;
  201.         }
  202.         else
  203.         {
  204.             //
  205.             //    NeXT doesn't document what error codes these generate, very well..
  206.             //
  207.             NXUngetc(TheFile);
  208.             [self StoreErrorCode: ERR_OK AndText: "Ungot it ok"];
  209.         }
  210.     }
  211.     return self;
  212. }
  213.  
  214.  
  215.  
  216. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  217. //    Method:        WriteText:
  218. //    Parameters:    the line of text we are to write
  219. //    Returns:     self
  220. //    Description:
  221. //        Writes the content6s of theLine out litterally, with no additional fiddling with.
  222. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  223. - WriteText: (CString) theLine
  224. {
  225.     [self Write: strlen(theLine) BytesFrom: (ByteString) theLine];
  226.     return self;
  227. }
  228.  
  229. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  230. //    Method:        WriteTextLine:
  231. //    Parameters:    the line of text we are to write
  232. //    Returns:     self
  233. //    Description:
  234. //        This writes out the speciied text, and follows it with a newline.
  235. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  236. - WriteTextLine: (CString) theLine
  237. {
  238.     [self Write: strlen(theLine) BytesFrom: (ByteString) theLine];
  239.     [self Write: 1 BytesFrom: (ByteString) "\n"];
  240.     return self;
  241. }
  242.  
  243.  
  244.  
  245. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  246. //    Method:        WriteTextUsing:WithFormat:
  247. //    Parameters:    A buffer provided by the caller, a format, and N arguments to be written
  248. //    Returns:     self
  249. //    Stores:        nothing (bug)
  250. //    Description:
  251. //        This writes out a text string given variable arguments
  252. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  253. - WriteTextUsing: (CString) buffer WithFormat: (CString) format, ...;
  254. {
  255.     va_list parameter_list;
  256.     
  257.     va_start(parameter_list, format);
  258.  
  259.     vsprintf(buffer, format, parameter_list);      // doc implies this does a va_end
  260.  
  261.     [self Write: strlen(buffer) BytesFrom: (ByteString) buffer];
  262.     return self;
  263. }
  264.  
  265.  
  266. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  267. //    Method:        AppendFrom:
  268. //    Parameters:    Another file object (opened)
  269. //    Returns:     self
  270. //    Stores:        nothing (bug)
  271. //    Description:
  272. //        This is a crude little routine that simply takes a file, assumes it is open and in
  273. //        place, reads the whole file into memory, and then writs it out into itself.
  274. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  275. - AppendFrom: sourceFile
  276. {
  277.     Integer size;
  278.     ByteString    buffer;
  279.  
  280.     size = [sourceFile FileSize];
  281.     buffer = NewByteString(size);
  282.     [sourceFile   MoveTo: 0];
  283.     [sourceFile Read: size BytesInto: buffer];
  284.     [self Write: size BytesFrom: buffer];
  285.     FreeByteString(buffer);
  286.     return self;
  287. }
  288.  
  289. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  290. //    Method:        WriteInteger:
  291. //    Parameters:
  292. //        An integer
  293. //    Returns:     self
  294. //    Stores:        none  explicitly (subcalls may)
  295. //    Description:
  296. //        This simply writes out an integer with a trailing space.  ooh ahh. 
  297. //    Bugs:
  298. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  299. - WriteInteger: (Integer) theInt
  300. {
  301.     CString    temp    = NewCString(15);
  302.     
  303.     [self   WriteTextUsing: temp WithFormat: "%d ", theInt];
  304.     
  305.     FreeCString(temp);
  306.     return self;
  307. }
  308.  
  309. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  310. //    Method:        WritePositiveInteger:
  311. //    Parameters:
  312. //        An integer
  313. //    Returns:     self
  314. //    Stores:        none  explicitly (subcalls may)
  315. //    Description:
  316. //        This simply writes out a positive integer with a trailing space.  yawn.
  317. //    Bugs:
  318. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  319. - WritePositiveInteger: (PositiveInteger) theInt
  320. {
  321.     CString    temp    = NewCString(15);
  322.     
  323.     [self   WriteTextUsing: temp WithFormat: "%u ", theInt];
  324.     
  325.     FreeCString(temp);
  326.     return self;
  327. }
  328.  
  329. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  330. //    Method:        WriteReal:
  331. //    Parameters:    A real number
  332. //    Returns:     self
  333. //    Stores:        none  explicitly (subcalls may)
  334. //    Description:
  335. //        This simply writes out a Real number with a trailing space..
  336. //    Bugs:
  337. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  338. - WriteReal: (Real) theReal
  339. {
  340.     CString    temp    = NewCString(31);
  341.     
  342.     [self   WriteTextUsing: temp WithFormat: "%.15f ", theReal];
  343.     
  344.     FreeCString(temp);
  345.     return self;
  346. }
  347.  
  348.  
  349. @end